home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4_src.zip / L2D.C < prev    next >
Text File  |  1995-01-21  |  54KB  |  1,243 lines

  1. /**************************************************************************\
  2. *                                                                          *
  3. *                                                                          *
  4. *    *****                      *****                                      *
  5. *      *****                  *****                                        *
  6. *        *****              *****                                          *
  7. *          *****          *****                                            *
  8. *            *****      *****                                              *
  9. *              *****  *****                                                *
  10. *            *****      *****                                              *
  11. *          *****          *****          The Firmware. The Net.            *
  12. *        *****              *****        Portable. Compatible.             *
  13. *      *****                  *****      Public Domain.                    *
  14. *    *****                      *****    By NORD><LINK.                    *
  15. *                                                                          *
  16. *                                                                          *
  17. *                                                                          *
  18. *    L2D.C   -   Level 2, Teil 4, zeitkritische Routinen                   *
  19. *                                                                          *
  20. *                Achtung: Ronner nicht auf diesen Code anwenden !          *
  21. *                                                                          *
  22. *                                                                          *
  23. *    angelegt:      DC4OX                                                  *
  24. *    modifiziert:                                                          *
  25. *         G8KBB April 1991 - change assembly names from trailing '?'to '_' *
  26. *                          - change function entry/exit to preserve IX     *
  27. *                          - change parameter offsets to account for IX!   *
  28. *                          - add deviation meter support to l1put()        *
  29. *                          - add minfre stats function to allocb();        *
  30. *                                                                          *
  31. * September 1993 - released as TheNet X-1J                                 *
  32. * Modified to add support for signal level meter                           *
  33. *                                                                          *
  34. * Released as TheNet X-1J release 4, January 1995                          *
  35. \**************************************************************************/
  36.  
  37.  
  38.  
  39. /* #define PORTABLE */        /* nicht portabler Code, einige Routinen,   */
  40.                               /* die einzigen laengeren Routinen, die aus */
  41.                               /* Interrupts heraus aufgerufen werden,     */
  42.                               /* werden assemberoptimiert (#asm/#endasm)  */
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*                                                             Includes   */
  49. /**************************************************************************/
  50.  
  51. #include "all.h"         /* allgemeine Festlegungen                       */
  52. #include "tntyp.h"       /* Festlegungen/Datenstrukturen fuer den Level 2 */
  53.  
  54.  
  55. #define ADC 0x20    /* address of ADC chip in I/O space */
  56.  
  57.  
  58. /*                                                            Externals   */
  59. /**************************************************************************/
  60. /* nicht aus L2EXT.H, da bei #asm-Deklarationen nicht wie vom C-Compiler  */
  61. /* sonst automatisch die doppelten Definitionen geloescht werden !        */
  62.  
  63. #ifdef PORTABLE
  64. extern             reset();
  65. extern             DIinc();
  66. extern             decEI();
  67. extern unsigned    nmbfre;
  68. extern LHEAD       freel;
  69. extern LHEAD       rxfl;
  70. extern LHEAD       stfl;
  71. extern LHEAD       trfl;
  72. extern LHEAD       txl2fl[];
  73. extern MBHEAD     *rxfhd[];
  74. extern MBHEAD     *txfhd[];
  75. #ifdef STATSCMD
  76. extern unsigned    minfre;
  77. #endif
  78. #ifdef MOD_MTU
  79. extern unsigned mtu_l2_max;
  80. #endif
  81. #ifdef METERS
  82. extern unsigned char sig_level;
  83. #endif
  84. #else
  85. #asm
  86.     .z80
  87.     extrn    reset_
  88.     extrn    nmbfre_
  89.     extrn    freel_
  90.     extrn    rxfl_
  91.     extrn    stfl_
  92.     extrn    trfl_
  93.     extrn    txl2fl_
  94.     extrn    rxfhd_
  95.     extrn    txfhd_
  96.     extrn    DIinc_
  97.     extrn    decEI_
  98.     extrn    ?ens
  99.     extrn    ?exs
  100.     extrn    ?en
  101.     extrn   minfre_
  102.  
  103. PAROFS    EQU    2    ; offset applied to parameters on stack
  104.             ; use 0 for NORDLINK, 2 for this version
  105. ADC     EQU     32    ; ADC chip address in I/O space
  106.  
  107. #endasm
  108. #ifdef MOD_MTU
  109. #asm
  110.     extrn   mtu_l2_max_
  111. #endasm
  112. #endif
  113. #asm
  114.  
  115. #endasm
  116. #ifdef METERS
  117. #asm
  118.     extrn   sig_level_
  119. #endasm
  120. #endif
  121. #asm
  122.  
  123. #endasm
  124. #endif
  125.  
  126.     
  127. #ifdef PORTABLE
  128. extern LEHEAD     *allocb();
  129. extern LEHEAD     *unlink();
  130. extern LEHEAD     *relink();
  131. #endif
  132.  
  133.  
  134.  
  135.  
  136.  
  137. /**************************************************************************\
  138. *                                                                          *
  139. * action      :  "level 1 put"                                             *
  140. *                                                                          *
  141. *                Je nach action Zeichen in den aktiven RX-Framebuffer      *
  142. *                schreiben, RX-Framebuffer auf den Muell werfen, oder      *
  143. *                RX-Framebuffer in RX-Frameliste einhaengen.               *
  144. *                                                                          *
  145.  **************************************************************************
  146. *                                                                          *
  147. * parameter   :  action  -                                                 *
  148. *                                                                          *
  149. *                  7  6543210 7654321  0                                   *
  150. *                +---+-------+-------+---+  RX-Framebuffer in RX-          *
  151. *                | 1 |  port |       | 0 |  Frameliste einhaengen,         *
  152. *                +---+-------+-------+---+  return NO                      *
  153. *                                                                          *
  154. *                +---+-------+-------+---+  falls RX-Framebuffer angelegt, *
  155. *                | 1 |  port |       | 1 |  diesen auf den Muell werfen    *
  156. *                +---+-------+-------+---+  (neuen beginnen), return NO    *
  157. *                                                                          *
  158. *                +---+-------+-----------+  Zeichen ch in aktiven RX-      *
  159. *                | 0 |  port |     ch    |  Framebuffer schreiben, ist es  *
  160. *                +---+-------+-----------+  das erste Zeichen, neuen       *
  161. *                                           RX-Framebuffer beginnen,       *
  162. *                                           entsprechend der einlaufenden  *
  163. *                                           Zeichen neue Datenbuffer       *
  164. *                                           allokieren und anhaengen,      *
  165. *                                           normal return NO, return YES,  *
  166. *                                           wenn Frame zu gross geworden   *
  167. *                                                                          *
  168. *                                           port gibt den verwendeten      *
  169. *                                           Empfangskanal an (HDLC/RS232)  *
  170. *                                                                          *
  171. * r/o globals :  -                                                         *
  172. *                                                                          *
  173. * r/w globals :  rxfhd   - Zeiger auf den Kopf des aktiven RX-Frames       *
  174. *                          0, wenn kein RX-Frame aktiv                     *
  175. *                rxfl    - Liste der empfangenen Frames                    *
  176. *                trfl    - Liste der Muell-Frames                          *
  177. *                                                                          *
  178. * locals      :  s.u.                                                      *
  179. *                                                                          *
  180. * returns     :  s.o.                                                      *
  181. *                                                                          *
  182. \**************************************************************************/
  183.  
  184. #ifdef PORTABLE
  185.  
  186. BOOLEAN l1put(action)
  187.  
  188. unsigned action;
  189.  
  190.   {
  191.     unsigned    port;         /* port aus action                          */
  192.     MBHEAD    **rxfbpp;       /* Zeiger auf Zeiger auf aktuelles RX-Frame */
  193.  
  194.     rxfbpp = &rxfhd[port = (action>>8) & 0x7F]; /* Adresse RX-Framezeiger */
  195.     if (!(action & 0x8000))                     /* Zeichen oder Befehl ?  */
  196.       {                                         /* Zeichen :              */
  197.         if (!*rxfbpp)                           /* RX-Frame aktiv ?       */
  198.           {
  199.             *rxfbpp = (MBHEAD *)allocb();       /* nein - neues anlegen   */
  200.             (*rxfbpp)->l2port = port;           /*        fuer port       */
  201.           }
  202.         putchr(action & 0xFF,*rxfbpp);          /* Zeichen in Frame       */
  203. #ifdef MOD_MTU
  204.         if ((*rxfbpp)->mbpc > mtu_l2_max)       /* Framelaengencheck      */
  205. #else
  206.         if ((*rxfbpp)->mbpc > L2MFLEN)          /* Framelaengencheck      */
  207. #endif
  208.           return (YES);
  209.       }
  210.     else                                        /* Befehl :               */
  211.       if (*rxfbpp)                              /* nur wenn Frame aktiv   */
  212.         {                                       /* Befehl ausfuehren      */
  213.           relink(*rxfbpp,action & 0x0001 ? trfl.tail : rxfl.tail);
  214. #ifdef METERS
  215.           (*rxfbpp)->rxdev = inp( ADC );        /* read ADC & store result*/
  216.           (*rxfbpp)->sig_level = sig_level; 
  217. #endif
  218.           *rxfbpp = NULL;                       /* kein RX-Frame aktiv    */
  219.         }
  220.     return (NO);                                /* default return NO      */
  221.   }
  222.  
  223. #else
  224.  
  225. #asm
  226.           public l1put_         ; globales Symbol
  227.  
  228. l1put_:   call  ?ens            ; IX/BC Stackframezeiger (Funktionsparameter)
  229.           defw  -4              ; und 4 Byte lokaler Variablenspeicher
  230.           ld    A,(IX+9+PAROFS) ; A = MSB(action) & 0x7F
  231.           and   127             ; (0x7F)
  232.           ld    (IX+0),A        ; port = A
  233.           add   A,A             ; rxfbpp = HL = &rxfhd[port]
  234.           ld    E,A
  235.           ld    D,0
  236.           ld    HL,rxfhd_
  237.           add   HL,DE
  238.           ld    (IX+2),L
  239.           ld    (IX+3),H
  240.           bit   7,(IX+9+PAROFS) ; Befehl oder Zeichen ?
  241.           jr    NZ,?lput2       ; Befehl ...
  242.  
  243.           ld    E,(HL)          ; Zeichen, DE = *rxfbpp = rxfhd[port]
  244.           inc   HL
  245.           ld    D,(HL)
  246.           ld    A,D             ; Empfangsframe aktiv (*rxfbpp != 0) ?
  247.           or    E
  248.           jr    NZ,?lput1       ; ja   -
  249.           push  HL              ; nein - rxfbpp merken
  250.           call  allocb_         ;        Freibuffer allokieren
  251.           ex    DE,HL           ;        DE = Adresse Freibuffer
  252.           pop   HL              ;        HL = rxfbpp
  253.           ld    (HL),D          ;        *rxfbpp = Adresse Freibuffer
  254.           dec   HL
  255.           ld    (HL),E
  256.           ld    HL,18           ;        Freibuffer->l2port = port
  257.           add   HL,DE
  258.           ld    A,(IX+0)
  259.           ld    (HL),A
  260.  
  261. ?lput1:   push  DE              ; putchr(LSB(action),*rxfbpp);
  262.           ld    L,(IX+8+PAROFS)
  263.           push  HL
  264.           call  putchr_
  265.           pop   DE
  266.           pop   DE              ; DE = *rxfbpp
  267.           ld    HL,10           ; DE = *rxfbpp->mbpc 
  268.           add   HL,DE
  269.           ld    E,(HL)
  270.           inc   HL
  271.           ld    D,(HL)
  272. #endasm
  273. #ifdef MOD_MTU
  274. #asm
  275.           ld    HL,(mtu_l2_max_) ;DE <= mtu_l2_max, Frame too long ?
  276. #endasm
  277. #else
  278. #asm
  279.           ld    HL,328          ; DE <= L2MFLEN, Frame noch nicht zu lang ? 
  280. #endasm
  281. #endif
  282. #asm
  283.           or    A
  284.           sbc   HL,DE
  285.           jr    NC,?lput5       ; ja   - Frame ok, return(NO);
  286.           ld    HL,1            ; nein - Frame zu lang, return(YES);
  287.           jr    ?lput6
  288.  
  289. ?lput2:   ld    E,(HL)          ; Befehl, DE = *rxfbpp
  290.           inc   HL
  291.           ld    D,(HL)
  292.           ld    A,D             ; Empfangsframe aktiv (*rxfbpp != 0) ?
  293.           or    E
  294.           jr    Z,?lput5        ; nein - return(NO);
  295.           bit   0,(IX+8+PAROFS) ; ja   - auf den Muell oder in RX-Liste ?
  296.           jr    NZ,?lput3       ; 
  297.           ld    HL,(rxfl_+2)    ; -> in RX-Liste, HL = rxfl.tail
  298.           jr    ?lput4
  299. ?lput3:   ld    HL,(trfl_+2)    ; -> auf den Muell, HL = trfl.tail
  300. ?lput4:   push  HL              ; relink(HL,*rxfbpp); (DE = *rxfbpp)
  301. ;
  302. #endasm
  303. #ifdef METERS
  304. #asm
  305.           ld    HL,20    ; point to rxdev in structure
  306.           add   HL,DE
  307.           in    A,(ADC)        ; read dev meter ADC channel (1)
  308.           ld    (HL),A        ; store dev reading
  309.           inc    hl        ; point to smeter entry
  310.           ld    A,(sig_level_)    ; read s-meter
  311.           ld    (hl),A        ; and save it
  312. #endasm
  313. #endif
  314. #asm
  315. ;
  316.           push  DE
  317.           call  relink_
  318.           pop   DE
  319.           pop   DE
  320.           ld    L,(IX+2)        ; HL = rxfbpp
  321.           ld    H,(IX+3)
  322.           xor   A
  323.           ld    (HL),A          ; *rxfbpp = 0
  324.           inc   HL
  325.           ld    (HL),A
  326. ?lput5:   ld    HL,0            ; return(NO);
  327. ?lput6:   ld    A,H
  328.           or    L
  329.           call  ?exs            ; alte Stackframezeiger einsetzen, lokalen
  330.           defw  4               ; Speicher zurueckgeben
  331. #endasm
  332.  
  333. #endif
  334.  
  335.  
  336.  
  337.  
  338.  
  339. /**************************************************************************\
  340. *                                                                          *
  341. * action      :  "level 1 get"                                             *
  342. *                                                                          *
  343. *                Sendeframebuffer verwalten. Je nach action Zeichen aus    *
  344. *                aktivem Sendeframe holen, Sendeframe rewind-en, oder      *
  345. *                alle zu sendenden Frames ohne Sendung in Gesendet-Liste   *
  346. *                umhaengen.                                                *
  347. *                Sind alle Zeichen aus einem Frame gelesen, wird es        *
  348. *                in die Gesendet-Liste umgehaengt.                         *
  349. *                                                                          *
  350.  **************************************************************************
  351. *                                                                          *
  352. * parameter   :  action  -                                                 *
  353. *                                                                          *
  354. *                  7  6543210 7654321  0                                   *
  355. *                +---+-------+-------+---+  falls ein Framebuffer TX-aktiv *
  356. *                | 1 |  port |       | 0 |  ist, diesen rewind-en, kein    *
  357. *                +---+-------+-------+---+  return-Wert                    *
  358. *                                                                          *
  359. *                +---+-------+-------+---+  aktiven Framebuffer und alle   *
  360. *                | 1 |  port |       | 1 |  zu sendenden                   *
  361. *                +---+-------+-------+---+  Frames in Gesendet-Liste       *
  362. *                                           umhaengen, kein return-Wert    *
  363. *                                                                          *
  364. *                +---+-------+-------+---+  Zeichen aus aktivem Frame      *
  365. *                | 0 |  port |       | 0 |  holen, dann return-Wert (s.u.) *
  366. *                +---+-------+-------+---+                                 *
  367. *                                                                          *
  368. *                                           Frame aktiv = haengt an txfr   *
  369. *                                                                          *
  370. *                                           port gibt den verwendeten      *
  371. *                                           Sendekanal an (HDLC/RS232)     *
  372. *                                                                          *
  373. * r/o globals :  -                                                         *
  374. *                                                                          *
  375. * r/w globals :  txfhdr  - Zeiger auf den Kopf des aktiven TX-Frames,      *
  376. *                          0, wenn kein TX-Frame aktiv                     *
  377. *                txl2fl  - Liste der zu sendenden (DWAIT) Level-2-Frames   *
  378. *                stfl    - Liste der gesendeten Frames                     *
  379. *                                                                          *
  380. * locals      :  s.u                                                       *
  381. *                                                                          *
  382. * returns     :  0x8001 - aktives Frame zuende, kein weiteren vorhanden    *
  383. *                0x8000 - aktives Frame zuende, noch weitere vorhanden     *
  384. *                0x00cc - naechstes Zeichen aus aktivem Frame              *
  385. *                                                                          *
  386. \**************************************************************************/
  387.  
  388. #ifdef PORTABLE
  389.  
  390. unsigned l1get(action)
  391.  
  392. unsigned action;
  393.  
  394.   {
  395.     unsigned    port;         /* port aus action                          */
  396.     MBHEAD    **txfbpp;       /* Zeiger auf Zeiger auf aktuelles TX-Frame */
  397.     LHEAD      *l2flp;        /* Zeiger auf DWAIT-Framelistenkopf         */
  398.  
  399.     txfbpp = &txfhd[port = (action>>8) & 0x7F]; /* Adresse TX-Framezeiger */
  400.     l2flp = &txl2fl[port];                      /* Sendeframelistenkopf   */
  401.     if (!(action & 0x8000))                     /* Zeichen oder Befehl ?  */
  402.       {                                         /* Zeichen :              */
  403.         if (!*txfbpp)                           /* wenn TX-Frame inaktiv  */
  404.           if (l2flp->head != l2flp)             /* aus der TX-Frameliste  */
  405.             unlink(*txfbpp = l2flp->head);      /* neues TX-Frame holen   */
  406.           else                                  /* sonst "keine weiteren  */
  407.             return (0x8001);                    /* Frames zu senden"      */
  408.         if ((*txfbpp)->mbgc < (*txfbpp)->mbpc)  /* wenn noch Zeichen im   */
  409.           return(getchr(*txfbpp) & 0xFF);       /* TX-Frame, eins holen   */
  410.         else 
  411.           {                                  /* sonst TX-Frame in         */
  412.             relink(*txfbpp,stfl.tail);       /* Gesendet-Liste,           */
  413.             *txfbpp = NULL;                  /* TX-Frame "inaktivieren",  */
  414.             if (l2flp->head != l2flp)        /* Status "noch Frames da /  */
  415.               return (0x8000);               /* nicht da" ermitteln und   */
  416.             return (0x8001);                 /* zurueckgeben              */
  417.           }
  418.       }
  419.     else                                     /* Befehl :                  */
  420.       if (!(action & 0x0001))                
  421.         {                                    /* wenn TX-Frame aktiv, dies */
  422.           if (*txfbpp) rwndmb(*txfbpp);      /* rewind-en                 */
  423.         }
  424.       else                                   /* alles in Gesendet-Liste   */
  425.         {
  426.           if (*txfbpp)                       /*   wenn TX-Frame aktiv     */
  427.             {                                /*   dies in Gesendet-Liste  */
  428.               relink(*txfbpp,stfl.tail);     /*   umhaengen und           */
  429.               *txfbpp = NULL;                /*   TX-Frame "inaktivieren" */
  430.             }
  431.           rlmlsl(l2flp);                     /*   def: alles gesendet !   */
  432.         }
  433.    }
  434.  
  435. #else
  436.  
  437. #asm
  438.           public l1get_         ; globales Symbol
  439.  
  440. l1get_:   call  ?ens            ; IX/BC Stackframezeiger (Funktionsparameter)
  441.           defw  -6              ; und 6 Byte lokaler Variablenspeicher
  442.           ld    A,(IX+11+PAROFS); A = MSB(action) & 0x7F
  443.           and   127             ; (0x7F)
  444.           ld    (IX+0),A        ; port = A
  445.           add   A,A             ; txfbpp = HL = &txfhd[port];
  446.           ld    E,A
  447.           ld    D,0
  448.           ld    HL,txfhd_
  449.           add   HL,DE
  450.           ld    (IX+2),L
  451.           ld    (IX+3),H
  452.           ld    HL,txl2fl_      ; l2flp = &txl2fl[port]
  453.           add   HL,DE
  454.           add   HL,DE
  455.           ld    (IX+4),L
  456.           ld    (IX+5),H
  457.           bit   7,(IX+11+PAROFS); Befehl oder Zeichen ?
  458.           jp    NZ,?lget5       ; Befehl ...
  459.  
  460.           ld    L,(IX+2)        ; Zeichen, HL = txfbpp
  461.           ld    H,(IX+3)
  462.           ld    E,(HL)          ; DE = *txfbpp = txfhd[port]
  463.           inc   HL
  464.           ld    D,(HL)
  465.           ld    A,D             ; Sendeframe aktiv, (*txfbpp != 0) ?
  466.           or    E
  467.           jr    NZ,?lget2       ; ja   -
  468.           push  HL              ; nein - (txfbpp merken)
  469.           ld    L,(IX+4)        ;        (HL = l2flp)
  470.           ld    H,(IX+5)        ;        (DE = l2flp->head)
  471.           ld    E,(HL)
  472.           inc   HL
  473.           ld    D,(HL)
  474.           dec   HL              ;        (Korrektur)
  475.           or    A               ;        l2flp->head == l2flp, d.h.
  476.           sbc   HL,DE           ;        TX-Frameliste leer ?
  477.           jr    NZ,?lget1
  478.           pop   HL              ;        ja   - Stack korrigieren
  479.           ld    HL,32769        ;               return(0x8001);
  480.           jp    ?lget8
  481. ?lget1:   pop   HL              ;        nein - *txfbpp = DE
  482.           ld    (HL),D          ;               (l2flp->head/diflp->head)
  483.           dec   HL
  484.           ld    (HL),E
  485.           push  DE
  486.           call  unlink_         ;               unlink(*txfbpp);
  487.           pop   DE              ;               (DE = *txfbpp)
  488.  
  489. ?lget2:   push  DE              ; (DE = *txfbpp)
  490.           push  DE
  491.           ld    HL,12           ; (push (*txfbpp)->mbgc)
  492.           add   HL,DE
  493.           ld    E,(HL)
  494.           inc   HL
  495.           ld    D,(HL)
  496.           pop   HL              ; (HL = *txfbpp)
  497.           push  DE
  498.           ld    DE,10           ; (DE = (*txfbpp)->mbpc)
  499.           add   HL,DE
  500.           ld    E,(HL)
  501.           inc   HL
  502.           ld    D,(HL)
  503.           pop   HL
  504.           or    A               ; if ((*txfbpp)->mbgc < (*txfbpp)->mbpc)
  505.           sbc   HL,DE           ;   return(getchr(*txfbpp) & 0xFF);
  506.           pop   DE              ; (DE = *txfbpp)
  507.           jr    NC,?lget3
  508.           push  DE
  509.           call  getchr_
  510.           pop   DE
  511.           ld    H,0
  512.           jp    ?lget8
  513.  
  514. ?lget3:   ld    HL,(stfl_+2)    ; else
  515.           push  HL              ;   {
  516.           push  DE              ;     relink(*txfbpp,stfl.tail);
  517.           call  relink_
  518.           pop   DE
  519.           pop   DE
  520.           ld    L,(IX+2)        ;     *txfbpp = NULL;
  521.           ld    H,(IX+3)
  522.           xor   A
  523.           ld    (HL),A
  524.           inc   HL
  525.           ld    (HL),A
  526.           ld    L,(IX+4)        ;     if (l2flp->head != l2flp)
  527.           ld    H,(IX+5)        ;       return (0x8000)
  528.           ld    E,(HL)
  529.           inc   HL
  530.           ld    D,(HL)
  531.           dec   HL
  532.           or    A
  533.           sbc   HL,DE 
  534.           ld    HL,0
  535.           jr    NZ,?lget4
  536.           inc   HL              ;     return (0x8001);
  537. ?lget4:   set   7,H             ;   }
  538.           jr    ?lget8
  539.  
  540. ?lget5:   bit   0,(IX+10+PAROFS); Befehl, alles in Gesendet-Liste umhaengen ?
  541.           jr    NZ,?lget6
  542.           ld    L,(IX+2)        ; nein - if (*txfbpp) rwndmb(*txfbpp);
  543.           ld    H,(IX+3)
  544.           ld    E,(HL)
  545.           inc   HL
  546.           ld    D,(HL)
  547.           ld    A,D
  548.           or    E
  549.           jr    Z,?lget8
  550.           push  DE
  551.           call  rwndmb_
  552.           pop   DE
  553.           jr    ?lget8
  554. ?lget6:   ld    L,(IX+2)        ; ja - if (*txfbpp)
  555.           ld    H,(IX+3)
  556.           ld    E,(HL)
  557.           inc   HL
  558.           ld    D,(HL)
  559.           ld    A,D
  560.           or    E
  561.           jr    Z,?lget7
  562.           push  HL              ;        {
  563.           ld    HL,(stfl_+2)    ;          relink(*txfbpp,stfl.tail);
  564.           push  HL
  565.           push  DE
  566.           call  relink_
  567.           pop   DE
  568.           pop   DE
  569.           pop   HL              ;          *txfbpp = NULL;
  570.           xor   A
  571.           ld    (HL),A
  572.           dec   HL
  573.           ld    (HL),A          ;        }
  574. ?lget7:   ld    L,(IX+4)        ;      rlmlsl(l2flp);
  575.           ld    H,(IX+5)
  576.           push  HL
  577.           call  rlmlsl_
  578.           pop   DE
  579. ?lget8:   ld    A,H
  580.           or    L
  581.           call  ?exs            ; alte Stackframezeiger einsetzen, lokalen
  582.           defw  6               ; Speicher zurueckgeben
  583. #endasm
  584.  
  585. #endif
  586.  
  587.  
  588.  
  589.  
  590.  
  591. /**************************************************************************\
  592. *                                                                          *
  593. * action      :  "relink message list to sent list"                        *
  594. *                                                                          *
  595. *                Frameliste in Gesendete-Frames-Liste umhaengen.           *
  596. *                                                                          *
  597.  **************************************************************************
  598. *                                                                          *
  599. * parameter   :  mlp     - in stfl umzuhaengende Frameliste                *
  600. *                                                                          *
  601. * r/o globals :  -                                                         *
  602. *                                                                          *
  603. * r/w globals :  stfl    - Liste der schon gesendeten Frames               *
  604. *                                                                          *
  605. * locals      :  -                                                         *
  606. *                                                                          *
  607. * returns     :  -                                                         *
  608. *                                                                          *
  609. \**************************************************************************/
  610.  
  611. #ifdef PORTABLE
  612.  
  613. VOID rlmlsl(mlp)
  614.  
  615. LEHEAD *mlp;
  616.  
  617.   {
  618.     while (mlp->nextle != mlp) relink(unlink(mlp->nextle),stfl.tail);
  619.   }
  620.  
  621. #else
  622.  
  623. #asm
  624.           public rlmlsl_        ; globales Symbol
  625.  
  626. rlmlsl_:  call  ?en             ; IX setzen (Funktionsparameterzeiger)
  627. ?rlml1:   ld    L,(IX+4+PAROFS) ; HL = mlp
  628.           ld    H,(IX+5+PAROFS)
  629.           ld    E,(HL)          ; DE = mlp->nextle
  630.           inc   HL            
  631.           ld    D,(HL)
  632.           dec   HL              ; (HL korrigieren)
  633.           or    A
  634.           sbc   HL,DE           ; mlp->nextle != mlp ?
  635.           jr    Z,?rlml2        ; nein - dann war's das
  636.           ld    HL,(stfl_+2)    ; ja   - relink(unlink(DE),stfl.tail);
  637.           push  HL
  638.           push  DE
  639.           call  unlink_
  640.           pop   DE
  641.           push  HL
  642.           call  relink_
  643.           pop   DE
  644.           pop   DE
  645.           jr    ?rlml1          ; while-Schleife
  646. ?rlml2:   pop   BC              ; Stack korrigieren
  647.           pop   IX              ; Aufruf
  648.           ret                   ; das war's
  649.  
  650. #endasm
  651.  
  652. #endif
  653.  
  654.  
  655.  
  656.  
  657.  
  658. /**************************************************************************\
  659. *                                                                          *
  660. * action      :  "put character"                                           *
  661. *                                                                          *
  662. *                Zeichen in Messagebuffer schreiben, Put-Counter erhoehen  *
  663. *                und Buffer-Pointer setzen. Ist der aktuelle Datenbuffer   *
  664. *                im Messagebuffer voll, dann neuen Datenbuffer allokieren  *
  665. *                und ans Datenbufferlistenende des Messagebuffers          *
  666. *                anhaengen.                                                *
  667. *                                                                          *
  668.  **************************************************************************
  669. *                                                                          *
  670. * parameter   :  ch      - in den Buffer zu schreibendes Zeichen           *
  671. *                mbhd    - Zeiger auf den Messagebuffer-Kopf, in den ch    *
  672. *                          zu schreiben ist                                *
  673. *                                                                          *
  674. * r/o globals :  -                                                         *
  675. *                                                                          *
  676. * r/w globals :  -                                                         *
  677. *                                                                          *
  678. * locals      :  -                                                         *
  679. *                                                                          *
  680. * returns     :  -                                                         *
  681. *                                                                          *
  682. \**************************************************************************/
  683.  
  684. #ifdef PORTABLE
  685.  
  686. VOID putchr(ch,mbhd)
  687.  
  688. char      ch;
  689. MBHEAD   *mbhd;
  690.  
  691.   {
  692.     if (!(mbhd->mbpc++ % 32))           /* neuer Datenbuffer faellig ?    */
  693.       mbhd->mbbp = ((MB *)(relink(allocb(),mbhd->mbl.tail)))->data; /* ja */
  694.     *mbhd->mbbp++ = ch;                 /* Zeichen in Buffer schreiben    */
  695.   }
  696.  
  697.  
  698. #else
  699.  
  700. #asm
  701.           public putchr_        ; globales Symbol
  702.  
  703. putchr_:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  704.           ld    L,(IX+6+PAROFS) ; HL = mbhd
  705.           ld    H,(IX+7+PAROFS)
  706.           push  HL              ; (merken)
  707.           ld    DE,10           ; ->mbpc
  708.           add   HL,DE
  709.           ld    E,(HL)          ; DE = mbhd->mbpc++
  710.           inc   HL
  711.           ld    D,(HL)
  712.           inc   DE
  713.           ld    (HL),D
  714.           dec   HL
  715.           ld    (HL),E
  716.           dec   DE              ; (DE wieder korrigieren)
  717.           pop   HL              ; HL = mbhd
  718.           ld    A,E
  719.           and   31              ; DE % 32 = 0, d.h. neuer Buffer erforderlich ?
  720.           jr    NZ,?put1        ; nein -
  721.           push  HL              ; ja   -
  722.           push  HL
  723.           ld    DE,8            ;        (SP) = mbhd->mbbp
  724.           add   HL,DE
  725.           ex    (SP),HL
  726.           ld    DE,6            ;        DE = mbhd->mbl.tail
  727.           add   HL,DE
  728.           ld    E,(HL)
  729.           inc   HL
  730.           ld    D,(HL)
  731.           push  DE
  732.           call  allocb_         ;        HL = Freibuffer (Adresse)
  733.           push  HL
  734.           call  relink_         ;        relink(Freibuffer,mbhd->mbl.tail)
  735.           pop   DE
  736.           pop   DE
  737.           ld    DE,4            ;        HL = Freibuffer->data
  738.           add   HL,DE
  739.           ex    DE,HL           ;        DE = Freibuffer->data
  740.           pop   HL              ;        HL = mbhd->mbbp (s.o. (SP) = ... )
  741.           ld    (HL),E          ;        mbhd->mbbp = DE
  742.           inc   HL
  743.           ld    (HL),D
  744.           pop   HL              ;        HL = mbhd
  745.  
  746. ?put1:    ld    DE,8            ; *mbhd->mbbp++ = ch
  747.           add   HL,DE
  748.           ld    E,(HL)
  749.           inc   HL
  750.           ld    D,(HL)
  751.           inc   DE              ; (++mbhd->mbbp)
  752.           ld    (HL),D
  753.           dec   HL
  754.           ld    (HL),E
  755.           dec   DE
  756.           ld    A,(IX+4+PAROFS)        ; (A = ch)
  757.           ld    (DE),A
  758.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  759.           pop   IX
  760.           ret                   ; das war's
  761. #endasm
  762.  
  763. #endif
  764.  
  765.  
  766.  
  767.  
  768.  
  769. /**************************************************************************\
  770. *                                                                          *
  771. * action      :  "get character"                                           *
  772. *                                                                          *
  773. *                Zeichen aus einem Messagebuffer holen. Datenbuffer-Poiner *
  774. *                setzen und Get-Count erhoehen. Uebergang in der           *
  775. *                Datenbufferliste vom Ende eines Datenbuffers zum          *
  776. *                naechsten ausfuehren.                                     *
  777. *                                                                          *
  778.  **************************************************************************
  779. *                                                                          *
  780. * parameter   :  mbhd    - Zeiger auf Kopf des Messagebuffers, aus dem     *
  781. *                          das Zeichen gelesen werden soll                 *
  782. *                                                                          *
  783. * r/o globals :  -                                                         *
  784. *                                                                          *
  785. * r/w globals :  -                                                         *
  786. *                                                                          *
  787. * locals      :  -                                                         *
  788. *                                                                          *
  789. * returns     :  aus dem Buffer gelesenes Zeichen                          *
  790. *                                                                          *
  791. \**************************************************************************/
  792.  
  793. #ifdef PORTABLE
  794.  
  795. getchr(mbhd)
  796.  
  797. MBHEAD *mbhd;
  798.  
  799.   {
  800.     if (!(mbhd->mbgc++ % 32))                            /* Ende Buffer ? */
  801.       mbhd->mbbp = ((MB *)(mbhd->mbbp)-1)->nextmb->data; /* ja, naechster */
  802.     return (*mbhd->mbbp++);                              /* Zeichen holen */
  803.   }
  804.  
  805. #else
  806.  
  807. #asm
  808.           public getchr_        ; globales Symbol
  809.  
  810. getchr_:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  811.           ld    L,(IX+4+PAROFS) ; HL = mbhd
  812.           ld    H,(IX+5+PAROFS)
  813.           push  HL              ; (merken)
  814.           ld    DE,12           ; A = mbhd->mbgc++ % 32
  815.           add   HL,DE
  816.           ld    E,(HL)          ; (DE = mbhd->mbgc)
  817.           inc   HL
  818.           ld    D,(HL)
  819.           inc   DE              ; (++mbhd->mbgc)
  820.           ld    (HL),D
  821.           dec   HL
  822.           ld    (HL),E
  823.           dec   DE              ; (DE wieder korrigieren)
  824.           pop   HL              ; (HL = mbhd)
  825.           ld    A,E             ; A = (D)E % 32
  826.           and   31              ; noch Zeichen im aktuellen Datenbuffer ?
  827.           jr    NZ,?get1        ; ja   -
  828.           push  HL              ; nein - mbhd sichern
  829.           ld    DE,8            ;        DE = mbhd->mbbp
  830.           add   HL,DE
  831.           ld    E,(HL)
  832.           inc   HL
  833.           ld    D,(HL)
  834.           push  HL              ;        (&mbhd->mbbp + 1 sichern)
  835.           ld    HL,-36          ;        HL = mbhd->mbbp - 36 
  836.           add   HL,DE           ;           = Zeiger auf den Datenbufferkopf
  837.           ld    E,(HL)          ;        DE = Datenbufferkopf.next
  838.           inc   HL
  839.           ld    D,(HL)
  840.           ld    HL,4            ;             + 4
  841.           add   HL,DE           ;        = Zeiger auf Anfang naechste Daten
  842.           ex    DE,HL           ;        in DE
  843.           pop   HL              ;        HL = &mbhd->mbbp + 1
  844.           ld    (HL),D          ;        (HL-1) = DE, also mbhd->mbbp =
  845.           dec   HL              ;        Anfang des naechsten Datenbuffers
  846.           ld    (HL),E
  847.           pop   HL              ;        HL = mbhd
  848.           
  849. ?get1:    ld    DE,8            ; HL = *mbhd->mbbp++
  850.           add   HL,DE           ; (DE = mbhd->mbbp)
  851.           ld    E,(HL)
  852.           inc   HL
  853.           ld    D,(HL)
  854.           inc   DE              ; (++mbhd->mbbp)
  855.           ld    (HL),D
  856.           dec   HL
  857.           ld    (HL),E
  858.           dec   DE              ; (DE wieder korrigieren)
  859.           ld    A,(DE)          ; (A = *DE)
  860.           ld    L,A             ; (HL = A)
  861.           ld    H,0
  862.           or    A               ; (C-Konvention)
  863.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  864.           pop   IX
  865.           ret                   ; das war's
  866. #endasm
  867.  
  868. #endif
  869.  
  870.  
  871.  
  872.  
  873.  
  874. /**************************************************************************\
  875. *                                                                          *
  876. * action      :  "rewind message buffer"                                   *
  877. *                                                                          *
  878. *                Message-Buffer (Kopf und Datenbufferliste) zuruecksetzen. *
  879. *                Get-Counter auf 0 setzen, Buffer-Pointer so setzen, dass  *
  880. *                beim naechsten getchr() auf das das erste Datenbyte des   *
  881. *                ersten Datenbuffers zugegriffen wird.                     *
  882. *                (Dies muss wie folgt geschehen, da der Get-Counter in     *
  883. *                jedem Fall auf 0 stehen muss und in getchr() auf % 32     *
  884. *                fuer das Positionieren auf den naechsten Datenbuffer      *
  885. *                abgetestet wird.)                                         *
  886. *                                                                          *
  887.  **************************************************************************
  888. *                                                                          *
  889. * parameter   :  mbhd    - Zeiger auf Kopf des Message-Buffers             *
  890. *                                                                          *
  891. * r/o globals :  -                                                         *
  892. *                                                                          *
  893. * r/w globals :  -                                                         *
  894. *                                                                          *
  895. * locals      :  -                                                         *
  896. *                                                                          *
  897. * returns     :  -                                                         *
  898. *                                                                          *
  899. \**************************************************************************/
  900.  
  901. #ifdef PORTABLE
  902.  
  903. VOID rwndmb(mbhd)
  904.  
  905. MBHEAD *mbhd;
  906.  
  907.   {
  908.     /* Kopf wie Datenbufferende */
  909.     mbhd->mbbp = (char *)(&((MBHEAD *)mbhd + 1)->mbl);
  910.     mbhd->mbgc = 0;                                    /* Bufferanfang    */
  911.   }
  912.  
  913. #else
  914.  
  915. #asm
  916.           public rwndmb_        ; globales Symbol
  917.  
  918. rwndmb_:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  919.           ld    E,(IX+4+PAROFS) ; DE = mbhd
  920.           ld    D,(IX+5+PAROFS)
  921.           push  DE              ; (fuer spaeter merken)
  922.           ld    HL,40           ; HL = &((MB *)mbhd + 1)->mbl
  923.           add   HL,DE
  924.           ex    DE,HL           ; DE = HL, HL = mbhd
  925.           ld    BC,8            ; mbhd->mbgc = DE
  926.           add   HL,BC
  927.           ld    (HL),E
  928.           inc   HL
  929.           ld    (HL),D
  930.           pop   HL              ; HL = mbhd
  931.           ld    DE,12           ; mbhd->mbgc = 0
  932.           add   HL,DE
  933.           xor   A
  934.           ld    (HL),A
  935.           inc   HL
  936.           ld    (HL),A
  937.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  938.           pop   IX
  939.           ret                   ; das war's
  940. #endasm
  941.  
  942. #endif
  943.  
  944.  
  945.  
  946.  
  947.  
  948. /**************************************************************************\
  949. *                                                                          *
  950. * action      :  "allocate buffer"                                         *
  951. *                                                                          *
  952. *                Leeren Buffer aus der Freiliste holen, Pogrammneustart    *
  953. *                wenn keine Buffer mehr in Freiliste.                      *
  954. *                                                                          *
  955.  **************************************************************************
  956. *                                                                          *
  957. * parameter   :  -                                                         *
  958. *                                                                          *
  959. * r/o globals :  -                                                         *
  960. *                                                                          *
  961. * r/w globals :  nmbfre  - Anzahl der Buffer in Freiliste freel            *
  962. *                freel   - verkettete Liste der freien Buffer              *
  963. *                                                                          *
  964. * locals      :  s.u.                                                      *
  965. *                                                                          *
  966. * returns     :  Zeiger auf freien Buffer, fall vorhanden                  *
  967. *                                                                          *
  968. \**************************************************************************/
  969.  
  970. #ifdef PORTABLE
  971.  
  972. LEHEAD *allocb()
  973.   {
  974.     LEHEAD *ret;                        /* Buffer Rueckgabewert           */
  975.  
  976.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  977.     if (!nmbfre--) reset();             /* Freibufferz., ggf. Neustart    */
  978.     ret = unlink(freel.head);           /* Buffer aus Liste aushaengen    */
  979. #ifdef STATSCMD
  980.     if( nmbfre < minfre )               /* if current notion of min bufs  */
  981.         minfre = nmbfre;                /* is < new count, then update it */
  982. #endif
  983.     decEI();                            /* Interrupts nun wieder erlaubt  */
  984.     return(ret);                        /* Zeiger auf Freibuffer zurueck  */
  985.   }
  986.  
  987. #else
  988.  
  989. #asm
  990.           public allocb_        ; globales Symbol
  991.  
  992. allocb_:  call  DIinc_          ; Interrupts verbieten (Listenkonsistenz)
  993.           ld    HL,(nmbfre_)    ; nmbfre--
  994.           dec   HL
  995.           ld    (nmbfre_),HL
  996.           inc   HL
  997.           ld    A,H             ; noch freie Buffer da ?
  998.           or    L
  999.           jr    NZ,?all1        ; ja   -
  1000.           call  reset_          ; nein - Programmneustart (Crash)
  1001. ?all1:
  1002. #endasm
  1003. #ifdef STATSCMD
  1004. #asm
  1005.           ld    DE,(minfre_)    ; put minfre value in DE
  1006.           ex    DE,HL           ; HL now has ninfre, DE has nmbfre
  1007.           scf
  1008.           sbc   HL,DE           ; determine whether it is lower
  1009.           jr    C,?all2
  1010.           ld    (minfre_),DE    ; and update minfre if so.
  1011. ?all2:
  1012. #endasm
  1013. #endif
  1014. #asm
  1015.           ld    HL,(freel_)     ; unlink(freel.head)
  1016.           push  HL
  1017.           call  unlink_
  1018.           call  decEI_          ; Interrupts wieder erlauben
  1019.           pop   HL              ; Zeiger auf Buffer zurueck
  1020.           ld    A,H             ; (C-Konvention)
  1021.           or    L
  1022.           ret                   ; das war's
  1023.  
  1024. #endasm
  1025.  
  1026. #endif
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032. /**************************************************************************\
  1033. *                                                                          *
  1034. * action      :  Element aus Liste aushaengen.                             *
  1035. *                                                                          *
  1036. *                                                                          *
  1037. *                      le ---+                                             *
  1038. *              vor           |     raus                hinter              *
  1039. *            +--------+      +-->+--------+          +--------+            *
  1040. *      ----->|        |--------->| prevle |--------->|        |----->      *
  1041. *            +--------+          +--------+          +--------+            *
  1042. *      <-----|        |<---------| nextle |<---------|        |<-----      *
  1043. *            +--------+          +--------+          +--------+            *
  1044. *            |        |          |        |          |        |            *
  1045. *                                                                          *
  1046. *                                                                          *
  1047. *                                \/                                        *
  1048. *                                                                          *
  1049. *                                                                          *
  1050. *             raus                    vor             hinter               *
  1051. *           +--------+              +--------+      +--------+             *
  1052. *    le --->| nextle |        ----->|        |----->|        |----->       *
  1053. *           +--------+              +--------+      +--------+             *
  1054. *           | prevle |        <-----|        |<-----|        |<-----       *
  1055. *           +--------+              +--------+      +--------+             *
  1056. *           |        |              |        |      |        |             *
  1057. *                                                                          *
  1058. *                                                                          *
  1059.  **************************************************************************
  1060. *                                                                          *
  1061. * parameter   :  le      - Zeiger auf auszuhaengendes Listenelement        *
  1062. *                                                                          *
  1063. * r/o globals :  -                                                         *
  1064. *                                                                          *
  1065. * r/w globals :  -                                                         *
  1066. *                                                                          *
  1067. * locals      :  -                                                         *
  1068. *                                                                          *
  1069. * returns     :  le                                                        *
  1070. *                                                                          *
  1071. \**************************************************************************/
  1072.  
  1073. #ifdef PORTABLE
  1074.  
  1075. LEHEAD *unlink(le)
  1076.  
  1077. LEHEAD *le;
  1078.  
  1079.   {
  1080.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  1081.     le->prevle->nextle = le->nextle;    /* Hinliste ohne le               */
  1082.     le->nextle->prevle = le->prevle;    /* Rueckliste ohne le             */
  1083.     decEI();                            /* Interrupts wieder erlaubt      */
  1084.     return(le);                         /* Zeiger auf das Element zurueck */
  1085.   }
  1086.  
  1087. #else
  1088.  
  1089. #asm
  1090.           public unlink_        ; globales Symbol
  1091.  
  1092. unlink_:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  1093.           call  DIinc_          ; Interrupts verbieten (Listenkonsistenz !)
  1094.           ld    L,(IX+4+PAROFS) ;   HL -> | raus |
  1095.           ld    H,(IX+5+PAROFS)
  1096.           push  HL              ;   le fuer return() merken
  1097.           ld    C,(HL)          ;   BC -> | hinter |
  1098.           inc   HL
  1099.           ld    B,(HL)
  1100.           inc   HL              ;   DE -> | vor |
  1101.           ld    E,(HL)
  1102.           inc   HL
  1103.           ld    D,(HL)
  1104.           dec   HL              ;   ( wieder HL -> | raus | ) 
  1105.           dec   HL
  1106.           dec   HL
  1107.           ex    DE,HL           ;   HL -> | vor |, DE -> | hinter|
  1108.           ld    (HL),C          ; * vor.nextle -> | hinter |
  1109.           inc   HL
  1110.           ld    (HL),B
  1111.           dec   HL
  1112.           inc   BC              ;   BC -> | hinter.prevle |
  1113.           inc   BC
  1114.           ld    A,L             ; * hinter.prevle -> | vor |
  1115.           ld    (BC),A 
  1116.           inc   BC
  1117.           ld    A,H
  1118.           ld    (BC),A
  1119.           call  decEI_          ;   Interrupts wieder erlauben
  1120.           pop   HL              ;   le holen ...
  1121.           ld    A,H             ;   ... und zurueckgeben
  1122.           or    L
  1123.           pop   BC              ;   alte Stackframezeiger wiedereinsetzen
  1124.           pop   IX
  1125.           ret                   ;   das war's
  1126. #endasm
  1127.  
  1128. #endif
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134. /**************************************************************************\
  1135. *                                                                          *
  1136. * action      :  Element in Liste einhaengen.                              *
  1137. *                                                                          *
  1138. *                                                                          *
  1139. *             neu                     vor             hinter               *
  1140. *           +--------+              +--------+      +--------+             *
  1141. *   new --->| nextle |     pred --->|        |----->|        |----->       *
  1142. *           +--------+              +--------+      +--------+             *
  1143. *           | prevle |        <-----|        |<-----|        |<-----       *
  1144. *           +--------+              +--------+      +--------+             *
  1145. *           |        |              |        |      |        |             *
  1146. *                                                                          *
  1147. *                                                                          *
  1148. *                                \/                                        *
  1149. *                                                                          *
  1150. *                                                                          *
  1151. *                     new ---+                                             *
  1152. *              vor           |     neu                 hinter              *
  1153. *            +--------+      +-->+--------+          +--------+            *
  1154. *   pred --->|        |--------->| prevle |--------->|        |----->      *
  1155. *            +--------+          +--------+          +--------+            *
  1156. *      <-----|        |<---------| nextle |<---------|        |<-----      *
  1157. *            +--------+          +--------+          +--------+            *
  1158. *            |        |          |        |          |        |            *
  1159. *                                                                          *
  1160. *                                                                          *
  1161.  **************************************************************************
  1162. *                                                                          *
  1163. * parameter   :  new     - Zeiger auf einzuhaengendes Listenelement        *
  1164. *                pred    - Zeiger auf Listenelement, hinter dem new        *
  1165. *                          eingehaengt werden soll                         *
  1166. *                                                                          *
  1167. * r/o globals :  -                                                         *
  1168. *                                                                          *
  1169. * r/w globals :  -                                                         *
  1170. *                                                                          *
  1171. * locals      :  -                                                         *
  1172. *                                                                          *
  1173. * returns     :  new                                                       *
  1174. *                                                                          *
  1175. \**************************************************************************/
  1176.  
  1177. #ifdef PORTABLE
  1178.  
  1179. LEHEAD *relink(new,pred)
  1180.  
  1181. LEHEAD *new;
  1182. LEHEAD *pred;
  1183.  
  1184.   {
  1185.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  1186.     new->nextle = pred->nextle;         /* Vorzeiger im neuen Element     */
  1187.     new->prevle = pred;                 /* Rueckzeiger im neuen Element   */
  1188.     new->nextle->prevle = new;          /* Rueckzeiger dahinter           */
  1189.     pred->nextle = new;                 /* Vorzeiger davor                */
  1190.     decEI();                            /* Interrupts wieder erlaubt      */
  1191.     return(new);                        /* Zeiger auf neues Element       */
  1192.   }
  1193.  
  1194. #else
  1195.  
  1196. #asm
  1197.           public relink_        ; globales Symbol
  1198.  
  1199. relink_:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  1200.           call  DIinc_          ; Interrupts verbieten (Listenkonsistenz !)
  1201.           ld    L,(IX+6+PAROFS) ;   HL -> | vor |
  1202.           ld    H,(IX+7+PAROFS)
  1203.           ld    E,(IX+4+PAROFS) ;   DE -> | neu |
  1204.           ld    D,(IX+5+PAROFS)
  1205.           push  DE              ;   new fuer return() merken
  1206.           ld    C,(HL)          ;   BC -> | hinter |     
  1207.           inc   HL
  1208.           ld    B,(HL)
  1209.           ld    (HL),D          ; * vor.nextle -> | neu |
  1210.           dec   HL
  1211.           ld    (HL),E
  1212.           ex    DE,HL           ;   HL -> | neu |, DE -> | vor |
  1213.           ld    (HL),C          ; * neu.nextle -> | hinter |
  1214.           inc   HL
  1215.           ld    (HL),B
  1216.           dec   HL
  1217.           inc   BC              ;   BC -> | hinter.prevle |
  1218.           inc   BC
  1219.           ld    A,L             ; * hinter.prevle -> | neu | 
  1220.           ld    (BC),A
  1221.           inc   BC
  1222.           ld    A,H
  1223.           ld    (BC),A
  1224.           inc   HL              ;   HL -> | neu.prevle |
  1225.           inc   HL
  1226.           ld    (HL),E          ; * neu.prevle -> | vor |
  1227.           inc   HL
  1228.           ld    (HL),D
  1229.           call  decEI_          ;   Interrupts wieder erlauben
  1230.           pop   HL              ;   new holen ...
  1231.           ld    A,H             ;   ... und zurueckgeben
  1232.           or    L
  1233.           pop   BC              ;   alte Stackframezeiger wiedereinsetzen
  1234.           pop   IX
  1235.           ret                   ;   das war's
  1236. #endasm
  1237.  
  1238. #endif
  1239.  
  1240.  
  1241.  
  1242. /* Ende von L2D.C */
  1243.